package emulator.hardware.memory;

import emulator.hardware.HwWord;
import emulator.hardware.debug.BusWatchException;

public class DebugMemoryBlock extends MemoryBlock {

	DebugMemoryFlags [] flags;
	
	public DebugMemoryBlock(int size)
	{
		super(size);

		flags = new DebugMemoryFlags [size];
		for (int i = 0; i < size; i++)
			flags[i] = new DebugMemoryFlags();
	}
	
	@Override
	synchronized public int read(int address) throws UnmappedMemoryException, BusWatchException {
		if (address >= memory.length)
			throw new UnmappedMemoryException(new HwWord(address));
		if (flags[address].isReadWatch())
			throw new BusWatchException("read", new HwWord(address));
		return ((int) memory[address]) & 0xFF;
	}

	@Override
	synchronized public void write(int address, int data) throws UnmappedMemoryException, BusWatchException {
		if (address >= memory.length)
			throw new UnmappedMemoryException(new HwWord(address));
		if (flags[address].isWriteWatch())
			throw new BusWatchException("write", new HwWord(address));
		if (!flags[address].isReadOnly())
			memory[address] = (byte) data;
	}
	
	synchronized public void enableReadWatch(int first, int last, boolean enable) {
		for (int i = first; i <= last; i++)
			flags[i].setReadWatch(enable);
	}

	synchronized public void enableWriteWatch(int first, int last, boolean enable) {
		for (int i = first; i <= last; i++)
			flags[i].setWriteWatch(enable);
	}

	public void enableReadonly(int first, int last, boolean enable) {
		for (int i = first; i <= last; i++)
			flags[i].setReadOnly(enable);
	}
}
